package org.zjvis.graph.analysis.service.exporter;

import com.alibaba.fastjson.JSONObject;
import org.zjvis.datascience.common.graph.vo.LinkVO;
import org.zjvis.datascience.common.graph.vo.NodeVO;
import org.zjvis.graph.analysis.service.util.GraphUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class ExporterCSV extends Exporter {
    List<String> nodeHead = Arrays.asList("id", "categoryId", "label", "attributes", "config");
    List<String> linkHead = Arrays.asList("id", "source", "target", "directed", "label", "weight", "attributes", "config");

    StringBuilder nodeSb;
    StringBuilder linkSb;

    public ExporterCSV() {

    }

    public boolean execute() {
        boolean ret = true;
        try {
            exportData();
        } catch (IOException e) {
            logger.warn("" + e.getMessage());
            ret = false;
        }
        return ret;
    }

    private void exportData() throws IOException{
        nodeSb.append(String.join(",", nodeHead)).append("\n");
        Iterator<NodeVO> nodeIter = nodes.iterator();
        while (nodeIter.hasNext()) {
            NodeVO node = nodeIter.next();
            exportCSVNode(node);
        }

        linkSb.append(String.join(",", linkHead)).append("\n");
        Iterator<LinkVO> linkIter = links.iterator();
        while (linkIter.hasNext()) {
            LinkVO link = linkIter.next();
            exportCSVLink(link);
        }
    }

    private void exportCSVNode(NodeVO node) {
        List<String> row = new ArrayList<>();
        row.add(node.getOrderId().toString());
        String categoryId = labelMap == null ? GraphUtil.removeAliasId(node.getCategoryId(), graphId) : labelMap.get(node.getCategoryId());
        row.add(fieldContentFormat(categoryId));
        row.add(fieldContentFormat(node.getLabel()));
        JSONObject attributes = new JSONObject();
        Exporter.makeAttributes(node.getAttrs(), attributes, node.getId(), node.getCategoryId(), multiValueHelper, metricResults);
        String attrStr = fieldContentFormat(attributes.toJSONString());
        row.add(attrStr);
        JSONObject config = new JSONObject();
        config.put("style", node.getStyle());
        config.put("labelCfg", node.getLabelCfg());
        config.put("type", node.getType());
        config.put("x", node.getX());
        config.put("y", node.getY());
        config.put("size", node.getSize());
        String cfgStr = fieldContentFormat(config.toJSONString());
        row.add(cfgStr);
        nodeSb.append(String.join(",", row)).append("\n");
    }

    private void exportCSVLink(LinkVO link) {
        List<String> row = new ArrayList<>();
        row.add(link.getOrderId().toString());
        row.add(GraphUtil.removeAliasId(link.getSource(), graphId));
        row.add(GraphUtil.removeAliasId(link.getTarget(), graphId));
        row.add(link.getDirected().toString());
        row.add(fieldContentFormat(link.getLabel()));
        row.add(link.getWeight().toString());
        JSONObject attributes = new JSONObject();
        Exporter.makeAttributes(link.getAttrs(), attributes, link.getId(), link.getEdgeId(), multiValueHelper, null);
        String attrStr = fieldContentFormat(attributes.toJSONString());
        row.add(attrStr);
        JSONObject config = new JSONObject();
        config.put("style", link.getStyle());
        config.put("labelCfg", link.getLabelCfg());
        config.put("type", link.getType());
        config.put("controlPoints", link.getControlPoints());
        config.put("curveOffset", link.getCurveOffset());
        String cfgStr = fieldContentFormat(config.toJSONString());
        row.add(cfgStr);
        linkSb.append(String.join(",", row)).append("\n");
    }

    public void setNodeSb(StringBuilder nodeSb) {
        this.nodeSb = nodeSb;
    }

    public void setLinkSb(StringBuilder linkSb) {
        this.linkSb = linkSb;
    }
}
